<template>
	<!-- 导入组件 -->
	<lay-layer v-model="visible" :title="title" :shade-opacity="0.5" :shade-close="false" :area="area" :btn="action">
		<div class="padding-lg">
			<lay-json-schema-form :model="formData" :useCN="true" :schema="formSchema" space="2">
				<!-- 文件路径 -->
				<template #filename>
					<div class="flex align-center">
						<lay-input v-model="formData.filename" :disabled="true">
							<template #append="{ disabled }">
								<lay-upload :key="layUploadKey" @on-change="onChange" :auto="false" :number="1" class="flex align-center justify-center">
									<template v-slot:default="params">
										选择文件
									</template>
								</lay-upload>
							</template>
						</lay-input>
						<lay-button @click="onUpload" type="normal" prefix-icon="layui-icon-upload" class="margin-left">读取数据</lay-button>
					</div>
				</template>
			</lay-json-schema-form>

			<lay-line contentPosition="left">
				<span class="text-xl">匹配结果</span>
			</lay-line>

			<!-- 表格 -->
			<div class="margin-top-lg margin-bottom-lg text-orange">
				<lay-icon type="layui-icon-tips-fill"></lay-icon> 请把人脸图片放入一个文件夹内，人脸图片名称请填写员工工号，打包成.zip压缩包上传
			</div>
			<pol-table :key="polTableKey" ref="polTableRef" v-bind="tableOpt">
				<!-- 字段名 -->
				<template #remove="{ row, rowIndex }">
					<lay-button size="xs" type="danger" @click="removeRow(rowIndex)">删除</lay-button>
				</template>
			</pol-table>
		</div>
	</lay-layer>
</template>

<script setup>
	import { ref, getCurrentInstance } from 'vue';
	import polTable from '@/components/polTable/polTable.vue'; //表格组件
	import CryptoJS from 'crypto-js'; //加密

	const { proxy } = getCurrentInstance();

	const props = defineProps({
		//当前操作的事件
		title: {
			type: String,
			default: '',
		},
		//导入模板类型，2员工
		targetKey: {
			type: String,
			default: '',
		}
	});
	const emit = defineEmits(['importExcelSuc', 'refreshData'])

	const loading = ref(false) //laoding
	const visible = ref(false);
	const area = ref(['1200px', '800px'])
	const exts = ref("zip")
	const importFile = ref() //导入文件file
	const layUploadKey = ref(new Date().getTime()) //上传组件的key用来刷新组件，解决同一个文件第二次上传时无法监听回调问题
	const fileSHA256 = ref() //上传文件的哈希值
	// 表单数据
	const model = {
		filename: '', //文件路径
		StrBase64: '', //文件base64
	};

	const formData = ref(JSON.parse(JSON.stringify(model)));

	//表单配置
	const formSchema = ref({
		filename: {
			label: '文件路径',
			slots: {
				customRender: 'filename',
			}
		},
	});

	//选择导入文件
	function onChange(files) {
		let name = files[0].name; //文件名
		var suffix = name.substr(name.lastIndexOf('.') + 1); //扩展名
		if (exts.value.indexOf(suffix) == -1) {
			proxy.$msg.err("选择的文件格式不正确，只有选择扩展名为[" + exts.value + "]的文件");
			return false;
		}

		let file = files[0];
		const reader = new FileReader();
		reader.onload = function(event) {
			const wordArray = CryptoJS.lib.WordArray.create(event.target.result)
			let fileSHA = CryptoJS.SHA256(wordArray).toString() //文件哈希值
			fileSHA256.value = fileSHA
		}
		reader.readAsArrayBuffer(file);

		action.value[0].disabled = true
		importFile.value = file
		formData.value.filename = name //赋值给文本框
		layUploadKey.value = new Date().getTime()
	}

	//表格配置
	const polTableKey = ref(0) //表格key用来刷新表格
	const columns = ref([
		{ title: '员工工号', key: 'StaffCode', align: 'center' },
		{ title: '员工姓名', key: 'StaffName', align: 'center' },
		{ title: '所属部门', key: 'DeptName', align: 'center' },
		{ title: '员工类别', key: 'StaffTypeName', align: 'center' },
		{ title: '电话', key: 'Tel', align: 'center' },
		{ title: '#', width: '90px', key: 'remove', align: 'center', customSlot: 'remove', fixed: 'right' },
	])
	const tableOpt = ref({
		columns: columns.value,
		localData: [], //本地数据
		height: '520px',
		isAutoHttp: false,
		defaultToolbar: false, //是否显示工具栏右边按钮
		showPermissionBtn: false, //是否显示工具栏权限按钮
		showCkb: false, //显示复选框
	});

	// 大文件分片上传
	async function onUpload() {
		if (!importFile.value) {
			proxy.$msg.err("请选择需要上传的一个文件");
			return false;
		}
		if (loading.value) return

		var chunkSize = 5 * 1024 * 1024; // 5 MB
		var totalChunks = Math.ceil(importFile.value.size / chunkSize);
		// 开始上传
		let errNum = 0
		loading.value = true
		let loadingIndex = proxy.$msg.loading()
		try {
			for (var i = 0; i < totalChunks; i++) {
				var start = i * chunkSize;
				var end = Math.min(importFile.value.size, start + chunkSize);
				var chunk = importFile.value.slice(start, end);

				let base64 = await promisFileReader(chunk) //获取切片的base64
				var formDataItem = new FormData();
				formDataItem.append('base64Data', base64);
				formDataItem.append('fileName', formData.value.filename);
				formDataItem.append('chunkIndex', i);
				formDataItem.append('totalChunks', totalChunks);
				formDataItem.append('FileExt', `.${exts.value}`);
				formDataItem.append('Sha256Hash', fileSHA256.value);

				let res = await proxy.$http.comm.UploadFile(formDataItem)
				console.log(res, i)
				if (res.code != 200) {
					errNum++
				}

				if (i === totalChunks - 1) {
					if (errNum == 0 && res.data.Fid) {
						uploadFaceImg(res.data.Fid, loadingIndex)
					} else {
						loading.value = false
						proxy.$msg.close(loadingIndex) //关闭loading
						proxy.$msg.err("文件上传失败，请重新上传！")
					}
				}

				if (res.data.Sha256Hash === fileSHA256 && res.data.Fid) {
					uploadFaceImg(res.data.Fid, loadingIndex)
					return false
				}
			}
		} catch (e) {
			loading.value = false
			proxy.$msg.close(loadingIndex) //关闭loading
			console.log('uploadFile', e)
		}
	}

	//获取切片的base64
	function promisFileReader(file) {
		return new Promise((resolve, reject) => {
			const reader = new FileReader();
			reader.readAsDataURL(file); //通过文件流将文件转换成Base64字符串
			reader.onload = (e) => resolve(e.target.result);
			reader.onerror = (e) => reject(e.target.error);
		});
	}

	//读取数据事件
	function uploadFaceImg(fig, loadingIndex) {
		// 结果
		const params = {
			fid: fig
		}
		proxy.$http.comm.uploadFaceImg(params).then(res => {
			tableOpt.value.localData = res.data
			action.value[0].disabled = false
			polTableKey.value = new Date().getTime()
			loading.value = false
			proxy.$msg.close(loadingIndex) //关闭loading
		}).catch(err => {
			loading.value = false
			proxy.$msg.close(loadingIndex) //关闭loading
		})
	}

	//删除行
	function removeRow(rowIndex) {
		console.log(rowIndex)
		tableOpt.value.localData.splice(rowIndex, 1);
	}

	//确定提交
	const action = ref([{
			text: '导入人脸',
			disabled: true,
			callback: () => {
				if (tableOpt.value.localData.length === 0) return proxy.$msg.err('需要导入的数据为空！')
				if (loading.value) return

				loading.value = true
				let loadingIndex = proxy.$msg.loading()
				proxy.$http.comm.saveFaceImg(tableOpt.value.localData).then(res => {
					loading.value = false
					proxy.$msg.close(loadingIndex) //关闭loading
					proxy.$msg.success('人脸导入成功！');
					visible.value = !visible.value;
					emit('importSuc') //成功通知父组件
					emit('refreshData') //成功通知父组件
					polTableKey.value = new Date().getTime()
				}).catch(err => {
					loading.value = false
					proxy.$msg.close(loadingIndex) //关闭loading
				})
			},
		},
		{
			text: '取消',
			callback: () => {
				visible.value = !visible.value;
			},
		},
	]);

	//控制导入弹窗显示隐藏
	function showPolImport() {
		visible.value = !visible.value;
	}

	defineExpose({
		showPolImport
	});
</script>

<style lang="scss">

</style>
